/*
 * Copyright 2010 Maxim Sokhatsky <maxim.sokhatsky@gmail.com>
 * All rights reserved. Distributed under the terms of the MIT license.
 */

#ifndef JABBER_PROTOCOL_H
#define JABBER_PROTOCOL_H

#include <QtXml/QXmlReader>
#include <QThread>

#include "XMLReader.h"
#include "XMLEntity.h"
#include "UserID.h"

class QSslSocket;
class QThread;
class QSemaphore;

enum JabberMessages { PORT_TALKER_DATA = 0x68374920 };

class ChatWindow;
//class BlabberMainWindow;

class JabberProtocol : public XMLReader
{
public:

    enum iq_intent {
        LOGIN,
        ROSTER,
        AGENTS,
        REGISTER,
        SEND_REGISTER,
        UNREGISTER,
        SEND_UNREGISTER,
        NEW_USER,
        MESSAGE,
        CHAT
    };

    JabberProtocol();
    ~JabberProtocol();

    void			SetConnection(QString host, int port, bool secure);
    void			SetCredentials(QString user, QString domain, QString pass);
    void			LogOn();
    void			RequestRoster();
    void			RequestInfo();
    void			Session();
    void			SendMessage(QString to, QString text);
    void			SendGroupchatMessage(QString to, QString text);
    void			SetStatus(QString status, QString message);
    void			ReceiveData(QVariant *msg);
    void			ReceivedMessageHandler(QVariant *jabberMessage);
    void			ProcessVersionRequest(QString req_id, QString req_from);
    void			Disconnect();
    void			Pong(QString id, QString from);
    void			LockXMLReader();
    void			UnlockXMLReader();
    void			OnStartTag(XMLEntity *entity);
    void			OnEndTag(XMLEntity *entity);
    void			OnEndEntity(XMLEntity *entity);
    void			OnTag(XMLEntity *entity);
    void			ParseRosterList(XMLEntity *entity);
    void			ProcessPresence(XMLEntity *entity);
    void			ParseStorage(XMLEntity *storage);
    void			SaveConference(UserID *conference);
    void			ProcessUserPresence(UserID *user, XMLEntity *entity);
    void			AcceptPresence(QString username);
    void			SendStorageRequest(QString tag, QString ns); // XEP-0049
    void			RejectPresence(QString username);
    char**			CreateAttributeMemory(int num_items);
    void			DestroyAttributeMemory(char **atts, int num_items);
    QString			GenerateUniqueID();
    void			SendSubscriptionRequest(QString username);
    void			SendUnsubscriptionRequest(QString username);
    void			AddToRoster(UserID *new_user);
    void			RemoveFromRoster(UserID *removed_user);
    void			SendMUCConferenceRequest(QString conference);
    void			SendMUCRoomRequest(QString room);
    void			SendUnavailable(QString to, QString status);
    void			SendAvailable(QString to, QString status);
    void			SendUserRegistration(QString username, QString password, QString resource);
    void			JoinRoom(QString to, QString pass);
    void			SendGroupPresence(QString _group_room, QString _group_username);
    void			RequestRoomOptions(QString room);

    QSslSocket  		*socketAdapter;
    QSystemSemaphore		*logged;
    QSystemSemaphore		*read_queue;
    QString			jid;
    QString			user;
    QString			domain;
    //BlabberMainWindow		*mainWindow;
    QSystemSemaphore            *xml_reader_lock;
    bool			_storage_supported;

private:

    bool			BeginSession();
    bool			Authorize();
    void			InitSession();
    void			Bind();
    void			StartDispatcher();

    QThread 			*reciever_thread;
    QString			host;
    int				port;
    QString			pass;
    bool			secure;


};

#endif // _H
